#ifndef _STD_CLASS_H_
#define _STD_CLASS_H_

#include "../../nonos/mcus/phy62xx/std_type.h"
#include "string.h"


/// @brief 静态定义一个字节缓冲区
/// @param name: 字节缓冲区指针变量名称
#define ByteBufferDef(name, size)	\
	u8 (__##name##_Buffer__)[size];											\
	ByteBuffer (__##name##_ByteBuffer__)((__##name##_Buffer__), size, 0);	\
	ByteBuffer *name = &(__##name##_ByteBuffer__)


/// @brief 简单的字符缓冲区
/// @attention 不支持并发操作
class ByteBuffer {
	u16 _size;      ///< 缓冲区尺寸
	u8 *_data;      ///< 数据存储空间
	u16 _dlen;      ///< 当前数据长度
	u32 _timestamp;	///< 最后一个数据的时间戳(ms)

public:
	/// 构造函数
	ByteBuffer(u8 *buf, u16 size, u16 dlen=0) { _data = buf; _size = size; _dlen = dlen; _timestamp = 0; }

	/// 数据的寿命(最后一个字节已经进来多长时间了，ms)
	u16 age();
	/// 缓冲区大小
	inline u16 size() { return _size; }
	/// 清除缓冲区数据
	inline void clear() { _dlen = 0; }
	/// 清除缓冲区数据，并初始化为 0
	inline void zero() { _dlen = 0; memset(_data, 0, _size); }
	/// 缓冲区数据长度
	inline u16 len() { return _dlen; }
	/// 缓冲区剩余空间长度
	inline u16 free() { return (_size-1) - _dlen; }
	/// 缓冲区数据长度强制增加
	inline void len_inc(u16 size) { _dlen += (free() >= size) ? size : 0; }
	/// 把缓冲中的数据当作字符串返回
	inline char* gets() { _data[_dlen] = '\0'; return (char*)_data; }
	/// 返回缓冲区中数据指针
	inline u8* getbs() { return _data; }

	/// 丢掉尾部 n bytes 数据
	inline void cut(u16 nbytes) { _dlen = (_dlen > nbytes) ? (_dlen - nbytes) : 0; }
	/// 左移 n bytes，丢掉头部 n bytes 数据
	void lshift(u16 nbytes);

	/// 放入一个字节
	bool put(char ch);
	/// 放入一块数据
	bool put(u16 len, const u8* data);
};


/// Bit 流
struct BitStream {
	u8 *bytes = NULL; // 数据缓冲区
	u16 size = 0;     // 可容纳的 Bit 数量
	u16 bitc = 0;     // 实际有效的 Bit 数量

	/// 构造函数(与 init() 配合使用)
	BitStream() {}
	/// 设置数据
	/// @param _bytes 数据缓冲区
	/// @param _size 可容纳的 Bit 数量
	/// @param bitc 实际有效的 Bit 数量
	void init(u8 *_bytes, u16 _size, u16 _bitc) { bytes = _bytes; size = _size; bitc = _bitc; }

	/// 构造函数
	/// @param _bytes 数据缓冲区
	/// @param _size 可容纳的 Bit 数量
	/// @param bitc 实际有效的 Bit 数量
	BitStream(u8 *_bytes, u16 _size, u16 _bitc) { bytes = _bytes; size = _size; bitc = _bitc; }

	/// 获取第几个bit
	u8 get(u16 idx) { return (idx > bitc) ? 0: BITn(bytes, idx); }
	/// 清零
	void clear() { memset(bytes, 0, (size>>3)); }
	/// 占用多少个字节
	u16 byteLen() { return (bitc>>3) + ((bitc&7)?1:0); }
	/// 在末尾添加一个bit
	void append(u8 bit) {
		if(bitc >= size) { return; }
		bytes[bitc>>3] |= bit<<(bitc&7);
		bitc++;
	}
};


/// 二进制字符串
struct BinaryString {
	u8 *data;
	u16 size;

	/// 构造函数
	BinaryString(u8 *_data, u16 _size) { size = _size; data = _data; }
};


/// 版本类
struct CVersion {
	Version _ver;

	CVersion(u8 majorVersion, u8 minorVersion, u16 buildNumber) {
		_ver.st.buildNumber    = buildNumber;
		_ver.st.minorVersion   = minorVersion;
		_ver.st.majorVersion   = majorVersion;
	}

	/// @brief 与另一个版本相比较
	/// @retval >0: 本版本号大于指定版本号
	/// @retval =0: 本版本号等于指定版本号
	/// @retval <0: 本版本号小于指定版本号
	int compareTo(CVersion ver) {
		if (_ver.dw > ver._ver.dw) {
			return 1;
		} else if (_ver.dw < ver._ver.dw) {
			return -1;
		} else {
			return 0;
		}
	}

	/// @brief 与另一个版本相比较
	/// @retval >0: 本版本号大于指定版本号
	/// @retval =0: 本版本号等于指定版本号
	/// @retval <0: 本版本号小于指定版本号
	int compareTo(u8 majorVersion, u8 minorVersion, u16 buildNumber) {
		CVersion ver(majorVersion, minorVersion, buildNumber);
		return compareTo(ver);
	}
};


#endif // _STD_CLASS_H_
